\chapter{系统测试及结果分析}
\section{测试环境和测试方法}
用于测试的硬件环境包括一台阿里云服务器，配备4G内存、40G硬盘、四核处理器，运行Ubuntu 22.04操作系统，还有一台用于访问系统的笔记本电脑。\par
用于测试的软件环境包括用来浏览网页的Chrome浏览器，用来创建各个接口并执行接口测试的Apifox，用来模拟大量请求从而进行负载测试的JMeter，用来存储和管理代码的Git。\par
系统的全面测试包括功能测试、性能测试和安全测试。功能测试对各个功能模块进行功能验证，保证其功能符合预期。性能测试是测试系统在处理不同量级的并发请求时的响应速度，用到了测试工具JMeter。安全测试是测试系统在应对几种常见攻击手段时的表现，保证系统具有起码的安全性。\par
\section{功能测试及分析}
本节对系统的主要功能模块进行测试。\par
表5.1为注册功能测试用例表。测试结果与预期结果一致。\par
% 注册功能测试用例
\begin{table}[!htbp]
  \caption{注册功能测试用例表}
  \centering
  \setlength{\tabcolsep}{4pt}
  \renewcommand{\arraystretch}{1.3}
  \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}cccc}
    \toprule[2pt]
    用例编号 & 测试场景 & 测试步骤 & 预期结果\\
    \midrule
    REG\_001 & 正常注册 & \makecell[c]{1. 输入账号:zhangsanfeng\\ 2. 输入昵称:张三丰\\ 3. 设置密码\\ 4. 确认密码\\ 5. 点击“注册”按钮} & \makecell[c]{注册成功，\\跳转到用户页面}\\
    \addlinespace[5pt]
    REG\_002 & 账号已存在 & \makecell[c]{1. 输入已存在的账号\\(如zhangsanfeng)\\ 2. 填写其他信息\\ 3. 点击：“注册”按钮} & 提示“账号已存在”\\
    \addlinespace[5pt]
    REG\_003 & 密码不一致 & \makecell[c]{1. 输入账号\\ 2. 输入密码\\ 3. 确认密码与密码不同\\ 4. 点击“注册”按钮} & \makecell[c]{提示“两次输入\\的密码不一致”} \\
    \addlinespace[5pt]
    REG\_004 & 必填项为空 & \makecell[c]{1. 留空账号或密码字段\\ 2. 点击“注册”按钮} & \makecell[c]{提示“请填写\\所有必填字段”} \\
    \addlinespace[5pt]
    REG\_005 & 特殊字符测试 & \makecell[c]{1. 账号输入特殊字符\\ 2. 昵称输入特殊字符\\ 3. 完成注册} & 拒绝特殊字符 \\
    \bottomrule[2pt]
  \end{tabular*}
\end{table}
\newpage
下表5.2为登录功能测试用例表。测试结果与预期结果一致。\par
% 登录功能测试用例
\begin{table}[!htbp]
  \caption{登录功能测试用例表}
  \centering
  \setlength{\tabcolsep}{4pt}
  \renewcommand{\arraystretch}{1.3}
  \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}cccc}
    \toprule[2pt]
    用例编号 & 测试场景 & 测试步骤 & 预期结果\\
    \midrule
    LOGIN\_001 & 正确账号密码登录 & \makecell[c]{1. 输入已注册账号\\(如zhangsanfeng)\\ 2. 输入正确密码\\ 3. 点击“登录”按钮} & \makecell[c]{登录成功，\\ 跳转到系统主页}\\
    \addlinespace[5pt]
    LOGIN\_002 & 错误账号登录 & \makecell[c]{1. 输入未注册账号\\ 2. 输入任意密码\\ 3. 点击“登录”按钮} & \makecell[c]{显示“登录失败，\\用户不存在或密码错误”} \\
    \addlinespace[5pt]
    LOGIN\_003 & 正确账号错误密码 & \makecell[c]{1. 输入已注册账号\\ 2. 输入错误密码\\ 3. 点击“登录”按钮} & \makecell[c]{显示“登录失败，\\用户不存在或密码错误” }\\
    \addlinespace[5pt]
    LOGIN\_004 & 空账号登录 & \makecell[c]{1. 账号字段留空\\ 2. 输入密码\\ 3. 点击“登录”按钮} & 提示“请输入账号” \\
    \addlinespace[5pt]
    LOGIN\_005 & 空密码登录 & \makecell[c]{1. 输入账号\\ 2. 密码字段留空\\ 3. 点击“登录”按钮} & 提示“请输入密码” \\
    \bottomrule[2pt]
  \end{tabular*}
\end{table}

下表5.3为题目管理功能测试用例表。测试结果与预期结果一致。\par
% 题目管理功能测试用例
\begin{table}[!htbp]
  \caption{题目管理功能测试用例表}
  \centering
  \setlength{\tabcolsep}{4pt}
  \renewcommand{\arraystretch}{1.3}
  \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}cccc}
    \toprule[2pt]
    用例编号 & 测试场景 & 测试步骤 & 预期结果 \\
    \midrule
    PROB\_001 & 创建简单题目 & \makecell[c]{1. 输入标题:测试1\\ 2. 选择标签:easy\\ 3. 填写题目内容\\ 4. 设置时间/内存限制\\ 5. 添加测试用例\\ 6. 点击“提交”} & \makecell[c]{题目创建成功，\\显示在题目列表}\\
    \addlinespace[5pt]
    PROB\_002 & 创建编程题目 & \makecell[c]{1. 输入标题:简单加法\\ 2. 填写题目描述\\ 3. 设置输入输出格式\\ 4. 添加示例代码\\ 5. 点击“提交”} & \makecell[c]{编程题目创建成功，\\可被用户解答}\\
    \addlinespace[5pt]
    PROB\_003 & 题目内容验证 & \makecell[c]{1. 创建题目时留空标题\\ 2. 尝试提交} & 提示“请输入题目标题”\\
    \addlinespace[5pt]
    PROB\_004 & 测试用例验证 & \makecell[c]{1. 创建题目时不添加测试用例\\ 2. 尝试提交} & \makecell[c]{提示“请至少添加\\一个测试用例”}\\
    \bottomrule[2pt]
  \end{tabular*}
\end{table}

下表5.4为用户信息功能测试用例表。测试结果与预期结果一致。\par
\newpage
% 用户信息功能测试用例
\begin{table}[!htbp]
  \caption{用户信息功能测试用例表}
  \centering
  \setlength{\tabcolsep}{4pt}
  \renewcommand{\arraystretch}{1.3}
  \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}cccc}
    \toprule[2pt]
    用例编号 & 测试场景 & 测试步骤 & 预期结果\\
    \midrule
    USER\_001 & 查看用户信息 & \makecell[c]{1. 登录后点击“用户信息”\\ 2. 查看张三丰的个人页面} & 正确显示用户信息和个人简介\\
    \addlinespace[5pt]
    USER\_002 & 修改用户信息 & \makecell[c]{1. 在用户页面点击“修改”\\ 2. 更新个人简介\\ 3. 点击保存} & 显示“修改成功”，信息更新\\
    \addlinespace[5pt]
    USER\_003 & 提交列表查看 & \makecell[c]{1. 点击“提交列表”\\ 2. 查看历史提交记录} & 正确显示用户的所有提交记录 \\
    \addlinespace[5pt]
    USER\_004 & 用户权限验证 & \makecell[c]{1. 尝试普通用户创建题目} & 根据权限显示或隐藏创建功能 \\
    \bottomrule[2pt]
  \end{tabular*}
\end{table}

下表5.5为代码评测功能测试用例表。测试结果与预期结果一致。\par
% 代码评测功能测试用例
\begin{table}[!htbp]
  \caption{代码评测功能测试用例表}
  \centering
  \setlength{\tabcolsep}{4pt}
  \renewcommand{\arraystretch}{1.3}
  \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}cccc}
    \toprule[2pt]
    用例编号 & 测试场景 & 测试步骤 & 预期结果 \\
    \midrule
    JUDGE\_001 & 正确代码提交 & \makecell[c]{1. 选择“测试1”题目\\ 2. 输入正确代码\\ 3. 点击“提交”} & 显示“Accepted”，测试通过 \\
    \addlinespace[5pt]
    JUDGE\_002 & 错误代码提交 & \makecell[c]{1. 选择“简单加法”题目\\ 2. 输入有逻辑错误的代码\\ 3. 点击“提交”} & \makecell[c]{显示错误类型\\(如Wrong Answer)} \\
    \addlinespace[5pt]
    JUDGE\_003 & 超时代码测试 & \makecell[c]{1. 提交包含无限循环的代码} & \makecell[c]{显示“Time \\Limit Exceeded”} \\
    \addlinespace[5pt]
    JUDGE\_004 & 内存超出测试 & \makecell[c]{1. 提交大量分配内存的代码} & \makecell[c]{显示“Memory \\Limit Exceeded”} \\
    \bottomrule[2pt]
  \end{tabular*}
\end{table}
功能测试均在系统中顺利完成，实际结果与预期结果一致，测试状态均为通过。测试用例涵盖了注册、登录、题目管理、用户信息、代码评测等主要功能模块，确保了系统的基本功能正常运行。\par
\section{性能测试及分析}
在评测环节，性能评测使用JMeter对系统的吞吐量以及响应时间进行考察，针对不同数量的并发请求进行50次测试。
测试结果数据，参见表5.6。\par
\begin{table}[!htbp]
  \caption{系统部分指标测试结果}
  \centering
  \setlength{\tabcolsep}{5pt}% column separation
  \renewcommand{\arraystretch}{1.5}%row space 
  \begin{tabular*}{35cc}{@{\extracolsep{\fill}}cccc}
    \toprule[2pt]
    并发数 & 平均响应时间 & 最大响应时间 & 响应率 \\
    \midrule
    1 & 0.376s & 0.376s & 100\% \\
    10 & 2.734s & 3.121s & 100\% \\
    50 & 4.860s & 5.590s & 100\% \\
    100 & 9.672s & 12.895s & 100\% \\
    500 & 11.709s & 13.568s & 98\% \\
    1000& 15.947s & 18.319s & 92\% \\
    \bottomrule[2pt]
  \end{tabular*}
\end{table}
测试结果显示，系统在应对不足50个并发请求时，响应时间在5秒以内，保证了用户体验。系统在应对高达100个并发请求时，依旧能达到100\%的响应率，响应时间也在15秒以内。系统在应对1000以下的并发量时，虽然会丢弃一些请求，但系统依旧可用，最大相应时间低于20秒。\par
根据测试数据绘制出平均响应时间关于并发请求数的函数图像，如图5.1所示。\par
\begin{figure}[H]
  \centering
  \includegraphics[width=0.8\textwidth]{Img/img5.12}
  \caption{平均响应时间图}
\end{figure}

\section{安全性测试及分析}
共提交5种类型的代码，分别为J1、J2、J3、J4、J5，均为Java代码。\par
其中J1提交的代码是一个空字符串，用来测试编译错误的情况。J2带有while(1)循环，测试代码含有占用CPU时间资源代码的攻击情况。J3代码在while(1)中循环新建对象，测试代码中含有占用内存代码的攻击情况。J4代码有非法系统调用，包括write()、fork()等，测试含有越权代码的攻击情况。J5代码是正常可以通过的代码，作为对照组。以上5组代码用来测试系统收到恶意代码后的反馈。\par
测试结果如表5.7所示。\par
\begin{table}[!htbp]
  \caption{5种代码测试结果}
  \centering
  \setlength{\tabcolsep}{5pt}% column separation
  \renewcommand{\arraystretch}{1.5}%row space 
  \begin{tabular*}{35cc}{@{\extracolsep{\fill}}cccccc}
    \toprule[2pt]
    代码类型 & J1 & J2 & J3 & J4 & J5\\
    \midrule
            & 编译失败 & 编译通过 & 编译通过 & 编译通过 & 编译通过\\
    评测结果 &         & 运行失败 & 运行失败 & 运行失败 & 运行成功\\
            &         & 超时异常 & 内存溢出异常 & 捕获到非法调用 &  通过\\
    \bottomrule[2pt]
  \end{tabular*}
\end{table}
系统能够顺利地对五种代码执行评测，在编译和运行时能够识别异常代码。J1代码在编译时就返回异常值，提前退出。J2代码在达到5秒的运行时间上限后自动退出，返回超时异常。J3代码在达到Docker容器分配的内存上限512MB后自动退出，返回内存溢出异常。J4代码在运行时触发非法调用，因为其在Docker容器中运行，并未对外层机器造成有害影响，并且代码在返回后fork到了其执行了非法调用，提示提交代码的后端捕获到非法调用。J5作为对照组可以正常运行，并返回代码通过。\par
以上安全测试的结果符合预期目标。\par
